﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Services;

namespace ChatServer
{
    /// <summary>
    /// ChatServer API
    /// </summary>
    [WebService(Namespace = "http://localhost/", Description = "Educational example chat app.", Name = "ChatServer")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class ChatServices : WebService
    {
        /***********************
         *User Get Methods
         ***********************/
        #region UserGet

        /// <summary>
        /// Gets all users of the chat app
        /// </summary>
        [WebMethod]
        public List<User> GetUsers() { return Global.Users; }

        /// <summary>
        /// Get a user of the chat app
        /// </summary>
        [WebMethod]
        public User GetUser(User user) { return GetUserByUserID(user.UserID); }

        /// <summary>
        /// Returns the user of the give userID
        /// </summary>
        [WebMethod]
        public User GetUserByUserID(int userID)
        {
            return Global.Users.FirstOrDefault(user => user.UserID == userID);
        }

        #endregion

        /***********************
         * User Add Methods
         ***********************/
        #region UserAdd

        /// <summary>
        /// Adds a user to the chat app
        /// </summary>
        [WebMethod]
        public User AddUserByName(String name)
        {
            User user = new User(name);
            AddUser(user);
            return user;
        }

        /// <summary>
        /// Adds a user to the chat app
        /// </summary>
        [WebMethod]
        public User AddUser(User user)
        {
            Global.Users.Add(user);
            Message msgWelcome = new Message(user, string.Format("Welcome, {0}.", user.Name), user);
            PublishMessage(msgWelcome);
            return user;
        }

        #endregion

        /***********************
         * User Remove Methods
         ***********************/
        #region userRemove

        /// <summary>
        /// Remove a user of the chat app
        /// </summary>
        [WebMethod]
        public bool RemoveUserByID(int userID)
        {
            return RemoveUser(GetUserByUserID(userID));
        }

        /// <summary>
        /// Remove a user of the chat app
        /// </summary>
        [WebMethod]
        public bool RemoveUser(User user)
        {
            return Global.Users.Remove(user);
        }

        #endregion

        /***********************
         * User Update Methods
         ***********************/
        #region userUpdate

        /// <summary>
        /// Set the status of a user
        /// </summary>
        [WebMethod]
        public bool UpdateUserStatusByUserID(int userID, Status status)
        {
            User user = GetUserByUserID(userID);
            return user != null && UpdateUserStatus(user, status);
        }

        /// <summary>
        /// Set the status of a user
        /// </summary>
        [WebMethod]
        public bool UpdateUserStatus(User user, Status status)
        {
            user.Status = status;
            return UpdateUser(user);
        }

        /// <summary>
        /// Updates the user with the same ID
        /// </summary>
        [WebMethod]
        public bool UpdateUser(User user)
        {
            if (RemoveUserByID(user.UserID))
                AddUser(user);
            return false;
        }
        #endregion

        /***********************
         * Message Publish Methods
         ***********************/
        #region PublishMessage

        /// <summary>
        /// Publish a message
        /// </summary>
        [WebMethod]
        public void PublishMessage(Message message)
        {
            Global.Messages.Add(message);
        }

        #endregion

        /***********************
         * Message Retrieve Methods
         ***********************/
        #region RetrieveMessage

        /// <summary>
        /// Retrieve stacked messages of a user
        /// </summary>
        [WebMethod]
        public List<Message> RetreiveMessages(User user)
        {
            return RetreiveMessagesByUserID(user.UserID);
        }

        /// <summary>
        /// Retrieve stacked messages of a user
        /// </summary>
        [WebMethod]
        public List<Message> RetreiveMessagesByUserID(int userID)
        {
            List<Message> messages = Global.Messages.Where(message => message.To == userID).ToList();
            foreach (Message message in messages)
                Global.Messages.Remove(message);
            return messages;
        }
        #endregion
    }
}